TURN Server
What is this TURN server for?
In our architecture, Coturn is used to relay audio streams from the client browser to the Vosk speech-to-text API over WebRTC.
This ensures that even if the client is behind a strict NAT or firewall, the audio stream can still reach the server reliably.
Coturn also supports authentication and encryption, making the relay secure and robust.
The web applications using the dictation API
dictation-api.abair.ieallows users to dictate speech.
Without a TURN server
- Many users behind symmetric NATs or firewalls won’t be able to connect.
- STUN alone cannot traverse all NATs.
With TURN
- Connections succeed in almost all network environments.
- More bandwidth is used (because TURN relays all traffic), but reliability improves.
Protocols
- RFC 5766 — TURN: Traversal Using Relays around NAT.
- RFC 5389 — STUN: Session Traversal Utilities for NAT.
- RFC 5245 — ICE: Interactive Connectivity Establishment.
How does the client use it?
When the browser starts a WebRTC connection:
- It creates an
RTCPeerConnectionwith the following ICE server config:
iceServers: [
{
urls: 'turn:abair.ie:3478',
username: 'webrtcuser',
credential: 'password123'
}
]
- The browser sends a STUN Binding Request to discover reflexive (public) addresses.
- If direct connection fails, it sends Allocate and CreatePermission requests to the TURN server.
- TURN allocates a relay address on the server and relays all packets.
Configuration
Key configuration file: /etc/turnserver.conf
# Ports
listening-port=3478
tls-listening-port=5349
# External/public IP mapping to internal IP
external-ip=136.243.40.234/10.0.0.1
# Realm (must match browser authentication realm)
realm=abair.ie
# Authentication
lt-cred-mech
user=webrtcuser:password123
# Certificates for TLS/DTLS
cert=/etc/letsencrypt/live/abair.ie/fullchain.pem
pkey=/etc/letsencrypt/live/abair.ie/privkey.pem
# Logging
log-file=/var/log/turnserver.log
simple-log
# CLI password for admin
cli-password=<random_password>
Why is realm used?
- TURN uses the
realmto define a namespace of authentication credentials. - This means users defined (
webrtcuser:password123) are valid only under theabair.ierealm. - Subdomains are under the
abair.ierealm are also valid.
Monitoring and Debugging
Logs
- Main log:
/var/log/turnserver.log - Example of successful allocation:
session 00000001: new, realm=<abair.ie>, username=<webrtcuser>
session 00000001: realm <abair.ie> user <webrtcuser>: incoming packet ALLOCATE processed, success
Test from client
- Verify TURN allocates a relay:
turnutils_uclient -u webrtcuser -w password123 -p 3478 -t -T -v abair.ie
Check ports
ss -tulpen | grep 3478
Troubleshooting checklist
- TURN server running?
-
realminturnserver.confmatchesrealmexpected by client? - User
webrtcuserdefined for that realm? - Port
3478reachable from the Internet? - Logs show successful
ALLOCATEandCREATE_PERMISSIONrequests?